using System;
using Main.CropPlant;
using Main.Details;
using Main.Event;
using Main.Map;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using ZSW.Framework;
using ZSW.Framework.Utils;

namespace Main.UI
{
    public class CursorManager : ZSWF_InitMonoBehaviour
    {
        public static Vector3Int MouseGridPos => mouseGridPos;
        private GridMapManager gridMapManager;

        [Header("Cursor Sprite")]
        [SerializeField] private Sprite normal;
        [SerializeField] private Sprite tool;
        [SerializeField] private Sprite seed;
        [SerializeField] private Sprite item;

        private Sprite currentSprite;


        [Header("Element")]
        [SerializeField] private Image cursorImage;
        [SerializeField] private Image buildImage;

        [SerializeField] private RectTransform rectTransform;


        [SerializeField] private Camera mainCamera;
        [SerializeField] private Grid currentGrid;


        [Header("Properties")]
        /// <summary>
        /// 世界坐标
        /// </summary>
        [SerializeField] private Vector3 mouseWorldPos;
        /// <summary>
        /// 网格坐标
        /// </summary>
        [SerializeField] private static Vector3Int mouseGridPos;

        [SerializeField] private bool cursorEnable = false;
        [SerializeField] private bool cursorValid = true;

        [SerializeField] private ItemDetails currentItem;

        private Transform m_player;

        public override void Init()
        {
            base.Init();

            currentSprite = normal;
            SetCursorImage(currentSprite);

            gridMapManager = ZSWF_IOCContainer.Get<GridMapManager>();
            m_player = GameObject.FindGameObjectWithTag("Player").transform;

            mainCamera = Camera.main;

            MainEventSystem.ItemSelectEvent += OnItemSelect;
            MainEventSystem.BeforeLoadSceneEvent += OnBeforeSceneLoadedEvent;
            MainEventSystem.AfterLoadSceneEvent += OnAfterSceneLoadedEvent;
        }

        #region Event
        private void OnBeforeSceneLoadedEvent()
        {
            cursorEnable = false;
        }

        private void OnAfterSceneLoadedEvent()
        {
            currentGrid = FindObjectOfType<Grid>();
        }

        private void OnItemSelect(ItemDetails itemDetails, bool isSelected)
        {
            if (!isSelected)
            {
                currentSprite = normal;
                cursorEnable = false;
                currentItem = null;

                buildImage.gameObject.SetActive(false);
            }
            else
            {
                currentItem = itemDetails;

                // WORKFLOW: 选择不同物品后的光标切换
                currentSprite = itemDetails.ItemType switch
                {
                    ItemType.Seed => seed,
                    ItemType.Commodity => item,
                    ItemType.ChopTool => tool,
                    ItemType.BreakTool => tool,
                    ItemType.ReapTool => tool,
                    ItemType.WaterTool => tool,
                    ItemType.CollectTool => tool,
                    _ => normal
                };
                cursorEnable = true;

                if (itemDetails.ItemType == ItemType.Furniture)
                {
                    buildImage.SetActive(true);
                    buildImage.sprite = itemDetails.ItemOnWorldSprite;
                    buildImage.SetNativeSize();
                }
            }

            SetCursorImage(currentSprite);
        }
        #endregion


        private void Update()
        {
            rectTransform.position = Input.mousePosition;

            if (!IsPointOverUI() && cursorEnable)
            {
                CheckCursor();
                SetCursorImage(currentSprite);
                CheckInput();
            }
            else
            {
                SetCursorImage(normal);
            }

            if (Input.anyKeyDown)
            {
                Cursor.visible = false;
            }
        }

        /// <summary>
        /// 鼠标在有效范围内点击时
        /// </summary>
        private void CheckInput()
        {
            if (Input.GetMouseButtonDown(0) && cursorValid)
            {
                MainEventSystem.CallMouseClickedEvent(mouseWorldPos, currentItem);
            }
        }


        private void CheckCursor()
        {
            mouseWorldPos = mainCamera.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y,
                -mainCamera.transform.position.z));

            mouseGridPos = currentGrid.WorldToCell(mouseWorldPos);

            buildImage.rectTransform.position = Input.mousePosition;

            ZSWF_IOCContainer.Get<GridMapManager>().TryGetCrop(mouseWorldPos, out var crop);
            var playerGridPos = currentGrid.WorldToCell(m_player.position);
            if (!ZSWFUtil_Space.IsWithinDistanceOnAxes(playerGridPos, mouseGridPos, currentItem.ItemUseRadius))
            {
                SetCursorInvalid();
                return;
            }

            if (gridMapManager.TryGetCurrentSceneTileDetails(mouseGridPos, out TileDetails tileDetails))
            {
                // Log($"{tileDetails.IsValid(currentItem.ItemType)}");
                SetCursor(tileDetails.IsValid(currentItem, crop, mouseWorldPos));
            }
            else
            {
                SetCursorInvalid();
            }
        }

        private void SetCursor(bool state)
        {
            if (state)
            {
                SetCursorValid();
            }
            else
            {
                SetCursorInvalid();
            }
        }

        #region  Color&Sprite

        private void SetCursorValid()
        {
            cursorImage.color = Color.white;
            buildImage.color = Color.white;
            cursorValid = true;
        }

        private void SetCursorInvalid()
        {
            cursorImage.color = new Color(1, 0, 0, 0.5f);
            buildImage.color = new Color(1, 0, 0, 0.5f);
            cursorValid = false;
        }

        private void SetCursorImage(Sprite sprite)
        {
            cursorImage.sprite = sprite;
        }

        #endregion

        /// <summary>
        /// 是否碰到UI
        /// </summary>
        /// <returns></returns>
        private bool IsPointOverUI()
        {
            if (EventSystem.current)
            {
                return EventSystem.current.IsPointerOverGameObject();
            }
            else
            {
                return false;
            }
        }
    }

}